import amqp from 'amqplib'
import config from '../config/rabbitmq.js';

const queue_send = 'send_queue';    //发送队列
const queue_retry = 'send_queue_retry'    //重试队列
const queue_fail = 'send_queue_fail'      //失败队列 ，给人工查看错误
//如果交换机类型是fanout ,那么绑定的路由为空
const dlx_routing_exchange = 'dlx_routing_exchange' //交换机名称
const dlx_routing_key = 'dlx_routing_key'

// 声明一个延时消息交换机和一个队列
const delayedExchangeName = 'delayed_exchange';
const delayedQueueName = 'delayed_queue';

class RabbitProducer {
  constructor() {
    this.connect()
  }

  async connect () {
    try {
      this.connection = await amqp.connect(`amqp://${config.username}:${config.password}@${config.hostname}:${config.port}`);

      this.channel = await this.connection.createChannel()

      await this.channel.assertQueue(queue_send, { durable: true })
      //创建死信交换机
      await this.channel.assertExchange(dlx_routing_exchange)
      //绑定死信路由,绑定死信交换机
      await this.channel.bindQueue(queue_send, dlx_routing_exchange, dlx_routing_key)


      await this.channel.assertQueue(queue_retry,
        {
          durable: true,
          deadLetterExchange: dlx_routing_exchange,
          deadLetterRoutingKey: dlx_routing_key,
          messageTtl: 30 * 1000   //重试时间
        })
      //失败后
      await this.channel.assertQueue(queue_fail, { durable: true })


      await this.channel.assertExchange(delayedExchangeName, 'x-delayed-message', {
        arguments: { 'x-delayed-type': 'direct' }
      });
      await this.channel.assertQueue(delayedQueueName, { durable: true });

      // 将队列绑定到交换机上，并设置延时时间（例如10秒）
      await this.channel.bindQueue(delayedQueueName, delayedExchangeName, '', {
        'x-delay': 10000
      });
    }
    catch (err) {
      console.log('err', err);
    }
  }
  //发送队列 (channel是否要一直关闭)
  async sendToWorker (msg, count) {
    try {

      if (typeof msg == 'object') {
        msg = JSON.stringify(msg)
      }

      await this.channel.sendToQueue(queue_send, Buffer.from(msg), {
        deliveryMode: true,//表示消息需要持久化存储。
        //传递信息
        headers: {
          count
        }
      })
    }
    catch (err) {
      console.log('err', err);
    }

    console.log('msg', msg, count)
  }

  //发送队列 (channel是否要一直关闭)
  async sendToWorkerLater (msg, count, delay) {
    try {

      if (typeof msg == 'object') {
        msg = JSON.stringify(msg)
      }

      await this.channel.publish(delayedExchangeName, '', Buffer.from(msg), {
        deliveryMode: true,//表示消息需要持久化存储。
        //传递信息
        headers: {
          count,
          'x-delay': delay
        },

      });
    }
    catch (err) {
      console.log('err', err);
    }

    console.log('msg', msg, count)
  }
}

let instance = new RabbitProducer();

export default instance;